package furns.filter;

import furns.utils.JDBCUtilsByDruid;

import javax.servlet.*;
import java.io.IOException;


//管理事务的过滤器
@SuppressWarnings("all")
public class TransactionFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        try {
            //执行 放行操作, 允许访问后续的过滤器或者目标资源
            filterChain.doFilter(servletRequest, servletResponse);
            //执行完后续的 过滤器或者目标资源后，进行事务提交。只有当事务提交后，数据库才会有修改。
            JDBCUtilsByDruid.commit();
        } catch (IOException e) {
            //在执行后续的过滤器或者目标资源时，捕获到异常，进行事务回滚
            /*
            注： 只要当 上方的 try{} 代码块中有异常抛出，才会执行该catch{}中的回滚方法。
                如果异常在 该类调用的某个方法中就已经被捕获，那么该catch{}中的回滚方法就不会执行。
                只有当异常被一直抛出到最高的层，才会执行该catch{}中的回滚方法。
            例如：生成订单时，首先调用 OrderServlet的saveOrder方法，由于反射机制会 再通过BasicServlet来调用该方法。
                 如果在BasicServlet中就已经将异常捕获，那么该catch{}中的回滚方法就不会执行。
                 只有BasicServlet将异常再次抛出给上一层时，才会执行该catch{}中的回滚方法。
             */
            JDBCUtilsByDruid.rollback();
            //抛出异常，给到tomcat。tomcat会根据errorpage 来显示对应的页面
            throw new RuntimeException(e);
        }
    }
    @Override
    public void destroy() {

    }
}
